package com.xxl.vueadmin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xxl.vueadmin.entity.SysMenu;
import com.xxl.vueadmin.entity.SysRole;
import com.xxl.vueadmin.entity.SysUser;
import com.xxl.vueadmin.mapper.SysMenuMapper;
import com.xxl.vueadmin.mapper.SysRoleMapper;
import com.xxl.vueadmin.mapper.SysUserMapper;
import com.xxl.vueadmin.service.ISysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxl.vueadmin.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xu
 * @since 2021-07-28
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
    @Resource
    SysRoleMapper roleMapper;

    @Resource
    SysMenuMapper sysMenuMapper;

    @Resource
    SysUserMapper sysUserMapper;
    @Autowired
    RedisUtils redisUtils;

    @Override
    public SysUser getBayUserName(String userName) {
        return getOne(new QueryWrapper<SysUser>().eq("username", userName));
    }

    @Override
    public String gerUserAuthority(String userId) {
        SysUser sysUser = sysUserMapper.selectById(userId);
        if(sysUser == null) {
            throw new RuntimeException("用户信息异常");
        }
        // 从缓存中获取权限信息,若存在则直接返回,不存在则查询数据库
        String authorityStr = "";
        String redisKey = "GrantAuthority:" + userId + "-" + sysUser.getUsername();
        if(redisUtils.hasKey(redisKey)) {
            authorityStr = (String)redisUtils.get(redisKey);
            return  authorityStr;
        }
        //
        // 根据用户主键获取角色信息,并拼接到权限字符串
        List<SysRole> roles = roleMapper.selectList(new QueryWrapper<SysRole>()
                .inSql("id", "select role_id from sys_user_role where user_id = " + userId));

        if(roles.size() > 0) {
            authorityStr = roles.stream().map(item ->  "ROLE_" + item.getCode())
                                         .collect(Collectors.joining(","));
        }
        // 根据用户主键获取权限信息,并拼接到权限字符串
        List<Long> permsIds = sysMenuMapper.getPermsIdByUid(userId);
        if(permsIds.size() > 0) {
            List<SysMenu> perms = sysMenuMapper.selectBatchIds(permsIds);
            boolean empty = perms.isEmpty();
            authorityStr = empty ? authorityStr : authorityStr.concat(",").concat(perms.stream()
                                                                                       .map(item -> item.getPerms())
                                                                                       .collect(Collectors.joining(",")));
        }
        redisUtils.set("GrantAuthority:" + userId + "-" + sysUser.getUsername(), authorityStr);
        return authorityStr;
    }

    @Override
    public void clearUserAuthority(String userId) {
        SysUser sysUser = sysUserMapper.selectById(userId);
        redisUtils.del("GrantAuthority:" + userId + "-" + sysUser.getUsername());
    }

    @Override
    public void clearRoleAuthority(String roleId) {
        List<SysUser> users = sysUserMapper.selectList(new QueryWrapper<SysUser>()
                .inSql("id", "select user_id from sys_user_role where role_id =" + roleId));
        if(users != null && users.size() > 0) {
            users.forEach(user -> {
                redisUtils.del("GrantAuthority:" + user.getId() + "-" + user.getUsername());
            });
        }
    }

    @Override
    public void clearMenuAuthority(String menuId) {
        List<SysUser> users = sysUserMapper.listByMenuId(menuId);
        if(users != null && users.size() > 0) {
            users.forEach(user -> {
                redisUtils.del("GrantAuthority:" + user.getId() + "-" + user.getUsername());
            });
        }
    }

}
